package com.ruoyi.ai.bootstrap;

import com.ruoyi.ai.service.VectorService;

import com.ruoyi.ai.domain.SysMenu;
import com.ruoyi.ai.mapper.SysMenuMapper;
import org.springframework.ai.reader.tika.TikaDocumentReader;

import com.ruoyi.ai.splitter.LineTextSplitter;
import com.ruoyi.ai.splitter.MarkdownSplitter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ai.document.Document;
import org.springframework.ai.transformer.splitter.TextSplitter;
import org.springframework.ai.transformer.splitter.TokenTextSplitter;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Component;


import java.util.*;
import java.util.stream.Collectors;

/**
 * 向量数据库初始化加载器
 * 该类负责在应用启动时初始化示例商品数据到向量数据库中
 * 实现CommandLineRunner接口以确保在Spring Boot应用启动时自动执行初始化逻辑
 *
 * @author tanxiaolong
 */
@Component
public class LoadVectorStore implements CommandLineRunner {
    /**
     * 日志记录器
     */
    private static final Logger logger = LoggerFactory.getLogger(LoadVectorStore.class);

    /**
     * 向量服务接口，用于商品数据的存储和检索
     */
    @Autowired
    private VectorService vectorService;

    @Autowired
    @Qualifier("milvusVectorStore")
    private  VectorStore vectorStore;

    @Autowired
    private SysMenuMapper sysMenuMapper;



    @Override
    public void run(String... args) throws Exception {
        logger.debug("开始初始化问题数据");
        if (args.length > 0) {
            logger.info("接收到参数: {}", args[0]);
        }

        // 初始化本地知识文档数据
//        if (Objects.requireNonNull(vectorService.searchQuestion("什么是重载，重载的理解，重载的优点，重载有什么用，重载的体系介绍")).isEmpty()) {
//            logger.debug("问题数据为空，重新加载");
//            List<Resource> list = List.of(
//                    new ClassPathResource("/doc/1-Java基础重要知识扫盲.md"),
//                    new ClassPathResource("/doc/常见问题.txt")
//            );
//            //读取文件
//            list.forEach(document -> {
//                TikaDocumentReader tikaDocumentReader = new TikaDocumentReader(document);
//                List<Document> documents = tikaDocumentReader.get();
//                TextSplitter textSplitter = null;
//                //判断Resource文档类型
//                if (Objects.requireNonNull(document.getFilename()).endsWith(".md")) {
//                    //使用MarkdownSplitter切分
//                    textSplitter = new MarkdownSplitter();
//                } else if (document.getFilename().endsWith(".txt")) {
//                    textSplitter = new LineTextSplitter();
//                } else {
//                    //使用TokenTextSplitter切分
//                    textSplitter = new TokenTextSplitter();
//                }
//                List<Document> splitDocuments = textSplitter.split(documents.get(0));
//                vectorStore.add(splitDocuments);
//                logger.info("初始化了{}个示例问题数据", splitDocuments.size());
//            });
//            logger.debug("初始化数据完毕");
//        }
        //初始化菜单路由数据
        if (Objects.requireNonNull(vectorService.searchQuestion2("高频面试题")).isEmpty()) {
            logger.debug("菜单路由数据为空，重新加载");

            // 从数据库查询所有菜单
            List<SysMenu> menus = sysMenuMapper.selectMenuTreeAll();

            // 创建map1: parent_id为0的菜单
            Map<Long, String> map1 = menus.stream()
                    .filter(menu -> menu.getParentId() == 0)
                    .collect(Collectors.toMap(SysMenu::getMenuId, SysMenu::getPath));

            // 创建map2: parent_id在map1中的菜单
            Map<Long, String> map2 = menus.stream()
                    .filter(menu -> map1.containsKey(menu.getParentId()))
                    .collect(Collectors.toMap(SysMenu::getMenuId, SysMenu::getPath));

            // 处理数据并创建Document列表
            List<Document> menuDocuments = new ArrayList<>();
            for (Map.Entry<Long, String> entry : map1.entrySet()) {
                Long parentId = entry.getKey();
                String parentPath = entry.getValue();

                // 遍历map2中所有parentId等于当前parentId的项
                for (SysMenu menu : menus) {
                    if (menu.getParentId().equals(parentId) && map2.containsKey(menu.getMenuId())) {
                        // 获取子菜单路径
                        String childPath = map2.get(menu.getMenuId());
                        // 拼接路径
                        String fullPath = parentPath + "/" + childPath;

                        // 创建metadata
                        Map<String, Object> metadata = new HashMap<>();
                        metadata.put("content", fullPath);

                        // 获取菜单名称
                        String menuName = menu.getMenuName();
                        

                        // 创建Document
                        Document doc = new Document(menuName, metadata);
                        menuDocuments.add(doc);

                        // 每10条数据存入一次向量库
                        if (menuDocuments.size() % 10 == 0) {
                            vectorStore.add(menuDocuments);
                            // 存入后清空列表
                            menuDocuments.clear();
                        }

                        // 处理最后不足10条的数据
                        if (menuDocuments.size() > 0 && (menuDocuments.size() % 10 != 0)) {
                            vectorStore.add(menuDocuments);
                        }
                    }
                }
            }


            logger.info("初始化了{}个菜单路由数据", menuDocuments.size());
            logger.debug("初始化数据完毕");
        }
    }
}
